package com.och.mrcp.core.mrcp.model;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Map;

/**
 * MRCPv2请求消息
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class MrcpRequest extends MrcpMessage {
    
    // 请求方法
    public enum Method {
        // 语音合成方法
        SPEAK("SPEAK"),
        STOP("STOP"),
        PAUSE("PAUSE"),
        RESUME("RESUME"),
        
        // 语音识别方法
        RECOGNIZE("RECOGNIZE"),
        INTERPRET("INTERPRET"),
        GETRESULT("GET-RESULT"),
        START_INPUT_TIMERS("START-INPUT-TIMERS"),
        DEFINE_GRAMMAR("DEFINE-GRAMMAR"),
        RECOGNIZE_ONESHOT("RECOGNIZE-ONESHOT"),
        GET_PARAMETER("GET-PARAMETER"),
        SET_PARAMETER("SET-PARAMETER");
        
        private final String value;
        
        Method(String value) {
            this.value = value;
        }
        
        public String getValue() {
            return value;
        }
        
        public static Method fromString(String value) {
            for (Method method : values()) {
                if (method.value.equalsIgnoreCase(value)) {
                    return method;
                }
            }
            throw new IllegalArgumentException("Unknown method: " + value);
        }
    }
    
    private Method method;
    private String requestId;  // 添加requestId字段
    
    public MrcpRequest() {
        super();
        this.messageType = MessageType.REQUEST;
    }
    
    public MrcpRequest(ResourceType resourceType, Method method) {
        this();
        this.resourceType = resourceType;
        this.method = method;
    }
    
    @Override
    public boolean isValid() {
        return resourceType != null && 
               method != null && 
               messageId != null && 
               !messageId.isEmpty();
    }
    
    @Override
    public String encode() {
        StringBuilder sb = new StringBuilder();
        
        // 第一行：MRCP版本 + 消息长度 + 方法 + 请求ID
        // 格式：MRCP/2.0 <message-length> <method> <request-id>
        int messageLength = calculateMessageLength();
        sb.append("MRCP/").append(MRCP_VERSION).append(" ")
          .append(messageLength).append(" ")
          .append(method != null ? method.getValue() : "UNKNOWN").append(" ")
          .append(requestId != null ? requestId : "0").append("\r\n");
        
        // 头部字段
        headers.forEach((name, value) -> 
            sb.append(name).append(": ").append(value).append("\r\n"));
        
        // 空行分隔头部和消息体
        sb.append("\r\n");
        
        // 消息体
        if (body != null && !body.isEmpty()) {
            sb.append(body);
        }
        
        return sb.toString();
    }
    
    /**
     * 计算消息长度
     * RFC 6787: 消息长度包括头部字段、空行分隔符和消息体，但不包括起始行
     * 使用UTF-8编码计算字节长度
     */
    private int calculateMessageLength() {
        try {
            // 计算头部长度（使用UTF-8编码）
            int headerLength = 0;
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String headerLine = entry.getKey() + ": " + entry.getValue() + "\r\n";
                headerLength += headerLine.getBytes("UTF-8").length;
            }
            
            // 计算消息体长度（使用UTF-8编码）
            int bodyLength = 0;
            if (body != null && !body.isEmpty()) {
                bodyLength = body.getBytes("UTF-8").length;
            }
            
            // 空行分隔符长度
            int separatorLength = "\r\n".getBytes("UTF-8").length;
            
            // 总长度 = 头部长度 + 空行分隔符 + 消息体长度
            return headerLength + separatorLength + bodyLength;
        } catch (Exception e) {
            // 如果UTF-8编码失败，回退到默认计算方式
            int headerLength = 0;
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                headerLength += entry.getKey().length() + ": ".length() + entry.getValue().length() + "\r\n".length();
            }
            int bodyLength = body != null ? body.length() : 0;
            int separatorLength = "\r\n".length();
            return headerLength + separatorLength + bodyLength;
        }
    }
    
    @Override
    public String getMessageTypeDescription() {
        return "MRCPv2 Request: " + (method != null ? method.getValue() : "UNKNOWN");
    }
    
    /**
     * 设置请求ID
     */
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
    
    /**
     * 获取请求ID
     */
    public String getRequestId() {
        return requestId;
    }
}
